package org.hepeng.workx.spring.cloud.netflix.zuul.fallback;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.codec.binary.StringUtils;
import org.hepeng.workx.exception.ApplicationRuntimeException;
import org.hepeng.workx.service.RestServiceCallResult;
import org.hepeng.workx.service.error.ServerError;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.util.Assert;

import java.io.ByteArrayInputStream;
import java.io.InputStream;

/**
 * @author he peng
 */
public class DefaultRestHttpResponseBodyProcessor implements CommonRouteFallbackProvider.HttpResponseBodyProcessor {

    private ObjectMapper objectMapper;

    public DefaultRestHttpResponseBodyProcessor(ObjectMapper objectMapper) {
        Assert.notNull(objectMapper , "objectMapper must not be null");
        this.objectMapper = objectMapper;
    }

    @Override
    public InputStream fallbackBody(CommonRouteFallbackProvider.ClientHttpResponseBuilder builder) {
        RestServiceCallResult.RestServiceCallResultBuilder callResultBuilder = new RestServiceCallResult.RestServiceCallResultBuilder();
        RestServiceCallResult callResult;
        if (org.apache.commons.lang3.StringUtils.isBlank(builder.getStatusText())) {
            callResult = callResultBuilder.error(ServerError.SERVER_ERROR).build();
        } else {
            callResult = callResultBuilder
                    .error(ServerError.SERVER_ERROR)
                    .msg(builder.getStatusText())
                    .build();
        }

        HttpHeaders headers = new HttpHeaders();
        headers.add(HttpHeaders.CONTENT_TYPE , MediaType.APPLICATION_JSON_UTF8_VALUE);
        builder.httpHeaders(headers);
        byte[] body;
        try {
            body = StringUtils.getBytesUtf8(this.objectMapper.writeValueAsString(callResult));
        } catch (JsonProcessingException e) {
            throw new ApplicationRuntimeException("jackson writeValueAsString error" , e);
        }
        return new ByteArrayInputStream(body);
    }
}
